%{
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
%}

%union {
    int          int_value;
    double       double_value;
}
%token <double_value> NUMBER
%token ADD SUB MUL DIV CR RB LB SIN
%type <double_value> expression term base_expression line line_list
%%
line_list
    :line
    | line_list line
    ;

line
    : expression CR
    {
        printf(">>>%f\n", $1);
    }
    ;

expression
    : term
    | expression ADD term
    {
        $$ = $1 + $3;
    }
    | expression SUB term
    {
        $$ = $1 - $3;
    }
    ;

term
    : base_expression
    | term MUL base_expression
    {
        $$ = $1 * $3;
    }
    | term DIV base_expression
    {
        $$ = $1 / $3;
    }
    ;

base_expression
    : NUMBER
    | SUB NUMBER
    {
        $$ = - $2;
    }
    | SIN LB expression RB
    {
        $$ = sin($3);
    }
    | LB expression RB
    {
        printf("$2 = %f", $2);
        $$ = $2;
    }
    ;

%%
extern int yylex (void);

int
yyerror(char const *str)
{
    extern char *yytext;
    fprintf(stderr, "parser error near %s\n", yytext);
    return 0;
}

int main(void)
{
    extern int yyparse(void);
    extern FILE *yyin;

    yyin = stdin;
    if (yyparse()) {
        fprintf(stderr, "Error ! Error ! Error !\n");
        exit(1);
    }
}
